package com.arpa.ntocc.common.common.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.arpa.ntocc.common.common.SpringContextHolder;
import com.arpa.ntocc.common.common.cache.*;
import com.arpa.ntocc.common.common.constant.StrConsts;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.domain.dto.ShipmentAuthorizationJsonBean;
import com.arpa.ntocc.common.domain.dto.UserInfoDTO;
import com.arpa.ntocc.common.domain.dto.WarehouseAuthorizationJsonBean;
import com.arpa.ntocc.common.domain.entity.PartyGroup;
import com.arpa.ntocc.common.domain.enums.ClientTypeEnum;
import com.arpa.ntocc.common.domain.enums.PartyTypeEnum;
import com.arpa.ntocc.common.service.authorize.AuthorizeTokenService;
import com.arpa.ntocc.common.service.impl.PartyGroupServiceImpl;
import com.google.common.collect.Lists;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Optional;

import static com.arpa.ntocc.common.domain.dto.UserInfoDTO.*;

/**
 * 用户工具类
 *
 * @Author liuyj
 * @Date 2019-11-19 08:52:47
 */
@Log4j2
public class UserUtil {

    private final static String AUTHORIZE_TOKEN_SERVICE = "authorizeTokenService";

    private final static String LOGIN_INFO_WITHOUT_EFFECT_PLEASE_RELOGIN = "登录信息无效，请重新登录！";
    /**
     * 获取当前登录用户code
     *
     * @return
     */
    public static String getCode() {
        try {
            AuthorizeTokenService authorizeTokenService = SpringContextHolder.getBean(AUTHORIZE_TOKEN_SERVICE);
            String partyCode = authorizeTokenService.getCurrentPartyCode();
            return Optional.ofNullable(partyCode).orElse("");
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
            return "";
        }
    }

    /**
     * 获取登录用户账号
     *
     * @return
     */
    public static String getLoginName() {
        try {
            PartyCacheDO partyCacheDO = getPartyCache();
            if (partyCacheDO != null && partyCacheDO.getPhone() != null) {
                return partyCacheDO.getPhone();
            }
            return "";
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
            return "";
        }
    }
    /**
     * 获取登录用户账号
     *
     * @return
     */
    public static String getName() {
        try {
            PartyCacheDO partyCacheDO = getPartyCache();
            if (partyCacheDO != null && partyCacheDO.getPhone() != null) {
                return partyCacheDO.getName();
            }
            return "";
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
            return "";
        }
    }

    /**
     * 获取登录用户所属机构code
     *
     * @return
     */
    public static String getBranchCode() {
        try {
            PartyCacheDO partyCacheDO = getPartyCache();
            if (partyCacheDO != null && partyCacheDO.getBranchCode() != null) {
                return partyCacheDO.getBranchCode();
            } else {
                //查询默认机构
                PartyGroupServiceImpl partyGroupServiceImpl = SpringContextHolder.getBean("partyGroupServiceImpl");
                PartyGroup partyGroup = partyGroupServiceImpl.getDefault();
                return Optional.ofNullable(partyGroup).map(PartyGroup::getCode).orElse("");
            }
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
            return "";
        }
    }

    /**
     * 获取当前登录用户的所属机构，
     * 并根据业务需要调整 当code为空时的处理或者根据机构level做特殊处理
     * 可选业务处理：
     * 1、可抛业务异常  throw new  ServiceException("当前用户所属机构不能为空")
     * 2、可查询所有数据，即返回空或null值
     * 3、可查询不到数据，即返回字符串“no”等数据库中不存在的所属机构代码
     *
     * @param type parameter参数、配置类   business 业务数据
     * @author liujiabao
     * @data 2020-3-25
     */
    public static String getBranchCodeByBusiness(final String type) {
        PartyGroupCacheDO partyGroupCacheDO = getBranch();
        String code;
        if (partyGroupCacheDO == null || StringUtils.isBlank(code = partyGroupCacheDO.getCode())) {
            throw new ServiceException("当前登录用户所属机构不能为空");
        }
        switch (type) {
            case "parameter"://参数类、配置类用户查看所属机构的数据
                return code;
            case "business"://业务类数据，集团总公司查看所有的，其他机构查看自己所属的数据
                return partyGroupCacheDO.getLevel() > 0 ? code : "";
            default:
                throw new ServiceException("UserUtil.getBranchCodeByBusiness参数错误");
        }

    }

    /**
     * 保存业务数据
     *
     * @return
     */
    public static String saveByBranchCode(String entityGroupCode) {
        PartyGroupCacheDO partyGroupCacheDO = getBranch();
        String code;
        if (partyGroupCacheDO == null || StringUtils.isBlank(code = partyGroupCacheDO.getCode())) {
            throw new ServiceException("当前登录用户所属机构不能为空");
        }
        return partyGroupCacheDO.getLevel() > 0 ? code : entityGroupCode;

    }

    /**
     * 获取登录用户所属机构
     *
     * @return
     */
    public static PartyGroupCacheDO getBranch() {
        try {
            PartyGroupCache partyGroupCache = SpringContextHolder.getBean("partyGroupCache");
            PartyCacheDO partyCacheDO = getPartyCache();
            if (partyCacheDO != null && partyCacheDO.getBranchCode() != null) {
                PartyGroupCacheDO partyGroupCacheDO = partyGroupCache.get(partyCacheDO.getBranchCode());
                return partyGroupCacheDO;
            } else {
                //查询默认机构
                PartyGroupServiceImpl partyGroupServiceImpl = SpringContextHolder.getBean("partyGroupServiceImpl");
                PartyGroup partyGroup = partyGroupServiceImpl.getDefault();
                PartyGroupCacheDO partyGroupCacheDO = BeanUtil.toBean(partyGroup, PartyGroupCacheDO.class);
                return partyGroupCacheDO;
            }
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
        }
        return null;
    }

    /**
     * 获取登录用户角色
     *
     * @return
     */
    public static PartyTypeEnum getPartyType() {
        try {
            PartyCacheDO partyCacheDO = getPartyCache();
            if (partyCacheDO != null && partyCacheDO.getPartyType() != null) {
                return partyCacheDO.getPartyType();
            }
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
        }
        return null;
    }

    /**
     * 判断用户是否是货主或发货企业
     *
     * @return
     */
    public static boolean isShipmentOrCompany() {
        try {
            PartyCacheDO partyCacheDO = getPartyCache();
            if (partyCacheDO != null && partyCacheDO.getPartyType() != null) {
                boolean result = partyCacheDO.getPartyType() == PartyTypeEnum.SHIPMENT || partyCacheDO.getPartyType() == PartyTypeEnum.SHIPMENT_COMPANY;
                return result;
            }
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
        }
        return false;
    }

    /**
     * 判断用户是否是独立货主
     *
     * @return
     */
    public static boolean isShipment() {
        try {
            PartyCacheDO partyCacheDO = getPartyCache();
            if (partyCacheDO != null && partyCacheDO.getPartyType() != null) {
                boolean result = partyCacheDO.getPartyType() == PartyTypeEnum.SHIPMENT;
                return result;
            }
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
        }
        return false;
    }

    /**
     * 判断用户code是否是独立货主
     *
     * @return
     */
    public static boolean isShipment(String partyCode) {
        try {
            PartyCache partyCache = SpringContextHolder.getBean("partyCache");
            PartyCacheDO partyCacheDO = partyCache.get(partyCode);
            if (partyCacheDO != null && partyCacheDO.getPartyType() != null) {
                boolean result = partyCacheDO.getPartyType() == PartyTypeEnum.SHIPMENT;
                return result;
            }
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
        }
        return false;
    }

    /**
     * 判断用户是否是发货企业
     *
     * @return
     */
    public static boolean isShipmentCompany() {
        try {
            PartyCacheDO partyCacheDO = getPartyCache();
            if (partyCacheDO != null && partyCacheDO.getPartyType() != null) {
                boolean result = partyCacheDO.getPartyType() == PartyTypeEnum.SHIPMENT_COMPANY;
                return result;
            }
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
        }
        return false;
    }

    /**
     * 判断用户是否是司机或车队长
     *
     * @return
     */
    public static boolean isDriver() {
        try {
            PartyCacheDO partyCacheDO = getPartyCache();
            if (partyCacheDO != null && partyCacheDO.getPartyType() != null) {
                boolean result = partyCacheDO.getPartyType() == PartyTypeEnum.DRIVER || partyCacheDO.getPartyType() == PartyTypeEnum.DRIVER_LEADER;
                return result;
            }
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
        }
        return false;
    }

    /**
     * 判断用户是否是独立司机
     *
     * @return
     */
    public static boolean isOnlyDriver() {
        try {
            PartyCacheDO partyCacheDO = getPartyCache();
            if (partyCacheDO != null && partyCacheDO.getPartyType() != null) {
                boolean result = partyCacheDO.getPartyType() == PartyTypeEnum.DRIVER;
                return result;
            }
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
        }
        return false;
    }

    /**
     * 判断用户是否是车队长
     *
     * @return
     */
    public static boolean isDriverLeader() {
        try {
            PartyCacheDO partyCacheDO = getPartyCache();
            if (partyCacheDO != null && partyCacheDO.getPartyType() != null) {
                boolean result = partyCacheDO.getPartyType() == PartyTypeEnum.DRIVER_LEADER;
                return result;
            }
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
        }
        return false;
    }

    /**
     * 获取登录用户
     *
     * @return
     */
    public static PartyCacheDO getPartyCache() {
        try {
            AuthorizeTokenService authorizeTokenService = SpringContextHolder.getBean(AUTHORIZE_TOKEN_SERVICE);
            PartyCache partyCache = SpringContextHolder.getBean("partyCache");
            String partyCode = authorizeTokenService.getCurrentPartyCode();
            if (StringUtils.isNotEmpty(partyCode)) {
                PartyCacheDO partyCacheDO = partyCache.get(partyCode);
                return partyCacheDO;
            } else {
                return null;
            }
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
            return null;
        }
    }



    /**
     * 登录客户端类型
     *
     * @return
     */
    public static ClientTypeEnum fromClientType() {
        try {
            AuthorizeTokenService authorizeTokenService = SpringContextHolder.getBean(AUTHORIZE_TOKEN_SERVICE);
            ClientTypeEnum clientTypeEnum = authorizeTokenService.getCurrentClientType();
            return clientTypeEnum;
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
            return null;
        }
    }


    /**
     * 获取登录用户
     *
     * @return
     */
    public static String getShipmentCompanyCode() {
        try {
            String partyCode = getLoginWarehouseCodeOrShipmentCode();
            if (StringUtils.isNotEmpty(partyCode)) {
                return partyCode;
            } else {
                log.error("找不到登录信息");
                throw new ServiceException("请先登录");
            }
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
            return null;
        }
    }

    /**
     * 获取登录货主名称
     *
     * @return
     */
    public static String getShipmentCompanyName() {
        try {
            ShipmentCache shipmentCache = SpringContextHolder.getBean("shipmentCache");
            String partyCode = getLoginWarehouseCodeOrShipmentCode();
            return shipmentCache.translate(partyCode);
        } catch (Exception e) {
            log.error(StrConsts.CATCH_MESSAGE, e);
            return "";
        }
    }


    /**
     * 获取登录时选择的仓库标识或货主标识
     *
     * @return
     */
//    public static String getLoginWarehouseCodeOrShipmentCode() {
//        AuthorizeTokenService authorizeTokenService = SpringContextHolder.getBean(AUTHORIZE_TOKEN_SERVICE);
//        UserInfoDTO userInfo = authorizeTokenService.getUserInfo();
//        Map<String, Object> authorizeData = userInfo.getAuthorizeData();
//        if (MapUtil.isNotEmpty(authorizeData)) {
//            return MapUtil.getStr(authorizeData, AUTHORIZE_DATA_CODE_KEY);
//        } else {
//            throw new ServiceException(LOGIN_INFO_WITHOUT_EFFECT_PLEASE_RELOGIN);
//        }
//    }

    public static String getLoginWarehouseCodeOrShipmentCode() {
        AuthorizeTokenService authorizeTokenService = SpringContextHolder.getBean(AUTHORIZE_TOKEN_SERVICE);
        UserInfoDTO userInfo = authorizeTokenService.getUserInfo();
        return userInfo.getShipmentCodeList().get(0);
    }

    /**
     * 获取登录时选择的仓库信息或货主信息
     *
     * @return
     */
    public static Object getLoginWarehouseOrShipment() {
        AuthorizeTokenService authorizeTokenService = SpringContextHolder.getBean(AUTHORIZE_TOKEN_SERVICE);
        UserInfoDTO userInfo = authorizeTokenService.getUserInfo();
        Map<String, Object> authorizeData = userInfo.getAuthorizeData();
        if (MapUtil.isNotEmpty(authorizeData)) {
            Map<String, Object> data = MapUtil.getAny(authorizeData, AUTHORIZE_DATA_KEY);
            return data.get(AUTHORIZE_DATA_KEY);
        } else {
            throw new ServiceException(LOGIN_INFO_WITHOUT_EFFECT_PLEASE_RELOGIN);
        }

    }

    /**
     * 获取授权仓库
     *
     * @return
     */
    public static List<Map<String, Object>>  getAuthorizeWarehouseList() {
        AuthorizeTokenService authorizeTokenService = SpringContextHolder.getBean(AUTHORIZE_TOKEN_SERVICE);
        UserInfoDTO userInfo = authorizeTokenService.getUserInfo();
        List<Map<String, Object>> warehouseList = userInfo.getWarehouseList();
        return warehouseList;

    }
    /**
     * 获取授权货主
     *
     * @return
     */
    public static List<Map<String, Object>>  getAuthorizeShipmentList() {
        AuthorizeTokenService authorizeTokenService = SpringContextHolder.getBean(AUTHORIZE_TOKEN_SERVICE);
        UserInfoDTO userInfo = authorizeTokenService.getUserInfo();
        List<Map<String, Object>> shipmentList = userInfo.getShipmentList();
        return shipmentList;

    }


    /**
     * 获取授权给登录用户的货主标识
     *
     * @return
     */
    public static List<String> getAuthorizeShipmentCodes() {
        AuthorizeTokenService authorizeTokenService = SpringContextHolder.getBean(AUTHORIZE_TOKEN_SERVICE);
        UserInfoDTO userInfo = authorizeTokenService.getUserInfo();
        return userInfo.getShipmentCodeList();
    }

   /**
    * 获取授权给登录用户的仓库标识
    * @author liuxr
    * @date 2021/12/1 14:00
    * @return java.util.List<java.lang.String>
    */
    public static List<String> getAuthorizeWarehouseCodes() {
        AuthorizeTokenService authorizeTokenService = SpringContextHolder.getBean(AUTHORIZE_TOKEN_SERVICE);
        UserInfoDTO userInfo = authorizeTokenService.getUserInfo();
        return userInfo.getWarehouseCodeList();
    }



//    /**
//     * 获取登录时选择的货主授权的仓库标识
//     *
//     * @return
//     */
//    public static List<String> getShipmentAuthorizeWarehouseCodes() {
////        AuthorizeTokenService authorizeTokenService = SpringContextHolder.getBean(AUTHORIZE_TOKEN_SERVICE);
//        UserInfoDTO userInfo = authorizeTokenService.getUserInfo();
//        Map<String, Object> authorizeData = userInfo.getAuthorizeData();
//        if (MapUtil.isNotEmpty(authorizeData)) {
//            String shipmentCode = MapUtil.getStr(authorizeData, AUTHORIZE_DATA_CODE_KEY);
//            String shipmentAuthorization = MapUtil.getStr(authorizeData, AUTHORIZE_SHIPMENT_CODES);
//            if (StrUtil.isNotBlank(shipmentAuthorization)) {
//                List<ShipmentAuthorizationJsonBean> shipmentAuthorizationJsonBeans =
//                        JSONUtil.toList(JSONUtil.parseArray(shipmentAuthorization), ShipmentAuthorizationJsonBean.class);
//                return shipmentAuthorizationJsonBeans.stream()
//                        .filter(r -> StrUtil.equals(shipmentCode, r.getShipment()))
//                        .map(ShipmentAuthorizationJsonBean::getWarehouse).findFirst().orElse(null);
//            }
//        }
//        throw new ServiceException(LOGIN_INFO_WITHOUT_EFFECT_PLEASE_RELOGIN);
//
//    }

    public static List<String> getShipmentAuthorizeWarehouseCodes() {
        AuthorizeTokenService authorizeTokenService = SpringContextHolder.getBean(AUTHORIZE_TOKEN_SERVICE);
        UserInfoDTO userInfo = authorizeTokenService.getUserInfo();
        return userInfo.getWarehouseCodeList();
    }

    /**
     * 获取登录用户授权的仓库信息
     *
     * @return
     */
    public static  List<WarehouseAuthorizationJsonBean>  getAuthorizeWarehouses() {
        AuthorizeTokenService authorizeTokenService = SpringContextHolder.getBean(AUTHORIZE_TOKEN_SERVICE);
        UserInfoDTO userInfo = authorizeTokenService.getUserInfo();
        Map<String, Object> authorizeData = userInfo.getAuthorizeData();
        if (MapUtil.isNotEmpty(authorizeData)) {
            List<WarehouseAuthorizationJsonBean> warehouseAuthorizationJsonBeans = Lists.newArrayList();
            String warehouseAuthorization = MapUtil.getStr(authorizeData, AUTHORIZE_WAREHOUSE_CODES);
            if (StrUtil.isNotBlank(warehouseAuthorization)) {
                warehouseAuthorizationJsonBeans =
                        JSONUtil.toList(JSONUtil.parseArray(warehouseAuthorization), WarehouseAuthorizationJsonBean.class);
            }
            return warehouseAuthorizationJsonBeans;
        }else {
            throw new ServiceException(LOGIN_INFO_WITHOUT_EFFECT_PLEASE_RELOGIN);
        }

    }

    /**
     * 获取登录用户授权的货主信息
     *
     * @return
     */
    public static  List<ShipmentAuthorizationJsonBean>  getAuthorizeShipments() {
        AuthorizeTokenService authorizeTokenService = SpringContextHolder.getBean(AUTHORIZE_TOKEN_SERVICE);
        UserInfoDTO userInfo = authorizeTokenService.getUserInfo();
        Map<String, Object> authorizeData = userInfo.getAuthorizeData();
        if (MapUtil.isNotEmpty(authorizeData)) {
            List<ShipmentAuthorizationJsonBean> shipmentAuthorizationJsonBeans = Lists.newArrayList();
            String shipmentAuthorization = MapUtil.getStr(authorizeData, AUTHORIZE_SHIPMENT_CODES);
            if (StrUtil.isNotBlank(shipmentAuthorization)) {
                shipmentAuthorizationJsonBeans =
                        JSONUtil.toList(JSONUtil.parseArray(shipmentAuthorization), ShipmentAuthorizationJsonBean.class);
            }
            return shipmentAuthorizationJsonBeans;
        }else {
            throw new ServiceException(LOGIN_INFO_WITHOUT_EFFECT_PLEASE_RELOGIN);
        }

    }


}
